<?php

namespace JsonLowCode\UI;

use JsonLowCode\Schema;
use JsonLowCode\Traits\Props\HasAccordion;
use JsonLowCode\Traits\Props\HasAnimated;
use JsonLowCode\Traits\Props\HasDraggable;
use JsonLowCode\Traits\Props\HasKeyboard;
use JsonLowCode\Traits\Props\HasMultiple;
use JsonLowCode\Traits\Props\HasSelectable;

/**
 * 树组件 Tree组件
 * @method static Tree make(array|string $data = []) Tree组件
 */
class Tree extends Schema
{
    protected string $componentName = "NTree";

    use HasAnimated, HasDraggable, HasAccordion, HasKeyboard, HasMultiple, HasSelectable;

    /**
     * @param array $data
     */
    public function __construct(array $data = [])
    {
        parent::__construct();
        $data && $this->data($data);
    }

//    /**
//     * 同 $this->data()
//     * @param array $children
//     * @return $this
//     */
//    public function children(array $children = []): static
//    {
//        return $this->data($children);
//    }

    /**
     * 树的节点数据。重新设置 data 会将一些非受控状态清空，如果你需要在使用中改动 data，最好以受控的方式控制树
     * @param array $data Array<TreeOption>
     * @return $this
     */
    public function data(array $data): static
    {
        return $this->prop('data', $data);
    }


    /**
     * 是否允许级联勾选还没有完全加载的节点。如果你要用这个属性，请记住 checked-keys 可能是不完整的，并且请注意勾选行为和后端计算逻辑的一致性，尤其是有禁用节点的情况下
     * @param bool|string $bool
     * @return $this
     */
    public function allowCheckingNotLoaded(bool|string $bool = true): static
    {
        return $this->prop('allow-checking-not-loaded', $bool);
    }

    /**
     * 一个不允许 drop 在叶节点内部的函数	是否允许 drop
     * @param string $value (info: { dropPosition: DropPosition, node: TreeOption, phase: 'drag' | 'drop' }) => boolean
     * @return $this
     */
    public function allowDrop(string $value = "(info)=>{ return true; }"): static
    {
        return $this->prop('allow-drop', $value);
    }

    /**
     * 是否显示选择框，需要将 cascade 设置为 true
     * @param bool|string $bool
     * @return $this
     */
    public function checkable(bool|string $bool = true): static
    {
        return $this->prop('checkable', $bool);
    }

    /**
     * 是否关联选项
     * @param bool|string $bool
     * @return $this
     */
    public function cascade(bool|string $bool = true): static
    {
        return $this->prop('cascade', $bool);
    }

    /**
     * 节点整行撑开
     * @param bool|string $bool
     * @return $this
     */
    public function blockLine(bool|string $bool = true): static
    {
        return $this->prop('block-line', $bool);
    }

    /**
     * 节点名称整行撑开
     * @param bool|string $bool
     * @return $this
     */
    public function blockNode(bool|string $bool = true): static
    {
        return $this->prop('block-node', $bool);
    }

    /**
     * 选中之后是否允许取消
     * @param bool|string $bool
     * @return $this
     */
    public function cancelable(bool|string $bool = true): static
    {
        return $this->prop('cancelable', $bool);
    }

    /**
     * 设置勾选策略来指定勾选回调返回的值，all 表示回调函数值为全部选中节点；parent 表示回调函数值为父节点（当父节点下所有子节点都选中时）；child 表示回调函数值为子节点
     * @param string $strategy all|parent|child
     * @return $this
     */
    public function checkStrategy(string $strategy = "all"): static
    {
        return $this->prop('check-strategy',$strategy);
    }

    /**
     * 复选框的位置
     * @param string $placement 'left' | 'right'
     * @return $this
     */
    public function checkboxPlacement(string $placement = 'left' | 'right'): static
    {
        return $this->prop('checkbox-placement',$placement);
    }

    /**
     * 替代 TreeOption 中的 children 字段名
     * @param string $field
     * @return $this
     */
    public function childrenField(string $field = 'children'): static
    {
        return $this->prop('children-field',$field);
    }

    /**
     * 替代 TreeOption 中的 key 字段名
     * @param string $field
     * @return $this
     */
    public function keyField(string $field = 'key'): static
    {
        return $this->prop('key-field',$field);
    }

    /**
     * 替代 TreeOption 中的 label 字段名
     * @param string $field
     * @return $this
     */
    public function labelField(string $field = 'label'): static
    {
        return $this->prop('label-field',$field);
    }

    /**
     * 替代 TreeOption 中的 disabled 字段名
     * @param string $field
     * @return $this
     */
    public function disabledField(string $field = 'label'): static
    {
        return $this->prop('disabled-field',$field);
    }

    /**
     * 如果设定则 checked 状态受控
     * @param string|array<string|integer> $keys
     * @return $this
     */
    public function checkedKeys(string|array $keys): static
    {
        return $this->prop('checked-keys',$keys);
    }

    /**
     * 是否允许点击节点进行勾选，仅在 checkable 为 true 时生效
     * @param string|bool $checkOnClick boolean | ((node: TreeOption) => boolean)
     * @return $this
     */
    public function checkOnClick(string|bool $checkOnClick = true): static
    {
        return $this->prop('check-on-click',$checkOnClick);
    }

    /**
     * 默认搜索的内容
     * @param string $pattern
     * @return $this
     */
    public function pattern(string $pattern): static
    {
        return $this->prop('pattern',$pattern);
    }

    /**
     * 如果设定则 selected 状态受控
     * @param string|array<string|integer> $keys
     * @return $this
     */
    public function selectedKeys(string|array $keys): static
    {
        return $this->prop('selected-keys',$keys);
    }

    /**
     * 如果设定 expanded-keys 则展开受控
     * @param string|array<string|integer> $keys
     * @return $this
     */
    public function expandedKeys(string|array $keys): static
    {
        return $this->prop('expanded-keys',$keys);
    }

    /**
     * 是否在点击节点后展开或收缩节点
     * @param string|bool $expandOnClick boolean | ((node: TreeOption) => boolean)
     * @return $this
     */
    public function expandOnClick(string|bool $expandOnClick = true): static
    {
        return $this->prop('expand-on-click',$expandOnClick);
    }

    /**
     * 节点的 HTML 属性
     * @param string $nodeProps info: { option: TreeOption }) => HTMLAttributes
     * @return $this
     */
    public function nodeProps(string $nodeProps = "(info)=>{}"): static
    {
        return $this->events('nodeProps', $nodeProps);
    }

    /**
     * 是否启用虚拟滚动，启用前你需要设定好树的高度样式
     * @param bool|string $bool
     * @return $this
     */
    public function virtualScroll(bool|string $bool = true): static
    {
        return $this->prop('virtual-scroll', $bool);
    }

}
